package fr.univnantes.lina.ftbcleaner;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import fr.univnantes.lina.ftbcleaner.DesambiguateUtil;
import fr.univnantes.lina.ftbcleaner.MultiWordDesambiguationCase;
import fr.univnantes.lina.ftbcleaner.WordAttributes;
import fr.univnantes.lina.ftbcleaner.WordForms;
import fr.univnantes.lina.ftbcleaner.WordLemma;
import fr.univnantes.lina.javautil.CollectionUtilities;


public class FTBPropertiesMultiWordAsSingleWordSequenceSearcher extends
		DesambiguateUtil {

	public FTBPropertiesMultiWordAsSingleWordSequenceSearcher() {
		super();
	}

	/**
	 * Search simple word sequences which correspond to multiwords components
	 * @param aWordForms TODO
	 *   
	 */
	public void searchSingleWordSequencesOfMultiWordsFromSimpleWordNodeList(
			NodeList aWordAttributeList, Map<String,Set<WordLemma>> multiWordsExpressionFirstWordMap, WordForms aWordForms) {
			
				//for(int i=0; (i < nodeList.getLength()); i++) displayDomTree(nodeList.item(i));
			
				//Map<String,MultiWordExpression> multiWordsExpressionHashMap = new HashMap<String,MultiWordExpression>() ;
			
				int numberOfMWOccurrencesCorrespondingToASWSeq = 0;
				int numberOfMWWithAtLeastOneCorrespondingSWSeq = 0;
				int numberOfAlreadyDesambiguatedCaseCorrespondingToASWSeq =0;
				Set<String> numberOfMWWithSeveralSWSeqFeaturesSet = new HashSet<String>();
			
				// searching sw sequence corresponding to mw 
				// for each sw occ
				for(int i=0; (i < aWordAttributeList.getLength()); i++) {
					if (aWordAttributeList.item(i) instanceof Element) {
						Element currentElement = (Element) aWordAttributeList.item(i);
			
						WordAttributes aSW =  WordAttributes.element2wordAttributes(currentElement);
			
						String currentWordFormOcc = (String) aSW.getWord();
						//NamedNodeMap aSWattrs = aSW.getAttributes();
						//int numAttrsInCurrentSW = aSWattrs.getLength();
						//System.out.println("Debug: getTagName "+ currentElement.getTagName()+" getTextContent "+ currentElement.getTextContent()+" numAttrs "+ currentElement.getAttributes().getLength());
			
						//System.out.println("Debug: if (multiWordsExpressionFirstWordMap.containsKey(aSW.getTextContent())) {");
						// if it exists a mw starting with this current word
						//System.out.println("Debug: currentWordFormOcc "+ currentWordFormOcc);
			
						if (multiWordsExpressionFirstWordMap.containsKey(currentWordFormOcc)) {
							
							//System.out.println("Debug: multiWordsExpressionFirstWordMap.containsKey(currentWordFormOcc)");
			
							// for each MW starting with the same word
							Set<WordLemma> mWSet = 	multiWordsExpressionFirstWordMap.get(currentWordFormOcc);
							Iterator<WordLemma> mWSetIterator = mWSet.iterator();
							while (mWSetIterator.hasNext()) {
								WordLemma aMW = mWSetIterator.next();
			
								// if we are not at the end of the document
								// do not need toconsider the number of amalgame since amalgame are removed in prior processing
								if (aMW.getSize()+i < aWordAttributeList.getLength()) {
			
									// check if there is sequence of simple word corresponding to the multi words
									// Identify if we are in presence of a form of the current MW starting with the same word
									Set<String> wordsSet = aMW.getWordsMap().keySet();
									Iterator<String> wordsIterator = wordsSet.iterator();
									
			
									// For each MW form
									while (wordsIterator.hasNext()) {
										String wordsString = wordsIterator.next();
										String wordArray[] = wordsString.split(" ");
										//System.out.println("Debug: wordsString "+wordsString+ " wordArray.length "+wordArray.length );
										//System.err.println("Debug: while (wordsIterator.hasNext()) { wordsString "+wordsString+ " aMW.getSize() "+ aMW.getSize()+ " wordArray.length "+ wordArray.length);
			
										
										// Do we consider the form which are not of the lemma size ? 
										// they may be ambiguous (belonging to various lemma)
										// no we don t
										if (aMW.getSize() == wordArray.length) {
			
											//System.err.println("Debug: aMW.getSize() == wordArray.length wordsString "+ wordsString+"");
			
											Boolean matched = true;
											// I do not know why, some multi words have only one word : Monde for "le monde"...
											// So a little hack
											//	
											/*for (int j = 1; j <wordArray.length ; j++ ) {
												for (int j = 0; j <wordArray.length ; j++ ) {
													//System.out.println("Debug: "+wordArray[j]+" compared to "+nodeList.item(i).getTextContent());
													// TODO unsecure if the following nodes are not Element
													if (!wordArray[j].equalsIgnoreCase(sWNodeList.item(i+j).getTextContent())) {
														matched = false;
													}
												}*/
											int j =0;
			
											// given the current mw form, we check word per word the alignement with a single word sequence
											while ((j <wordArray.length) && matched) {
												if (!wordArray[j].equalsIgnoreCase(WordAttributes.element2wordAttributes((Element)aWordAttributeList.item(i+j)).getWord())) {
													matched = false;
												}
												j++;
											}
			
											// one of the MW forms matches
											// it means we can take the information of the current sw seq for this MW 
											if (matched) {
			
												//System.err.println("Debug: wordsString "+ wordsString+" matched");
			
												//String features = "";
												// for each single word of the 
												String catSeq = "";
												String subcatSeq = "";
												String lemmaSeq = "";
												String mphSeq = "";
												for (int l = 0; l <wordArray.length ; l++ ) {
			
													WordAttributes currentSW = WordAttributes.element2wordAttributes((Element) aWordAttributeList.item(i+l));
													//NamedNodeMap currentSWattrs = currentSW.getAttributes();
													//int numberOfCurrentSWattrs = currentSWattrs.getLength();
													//System.out.println("Debug: "+ currentSW.getTagName()+" "+ currentSW.getTextContent()+" numAttrs "+ numberOfCurrentSWattrs);
													//System.out.println("Debug: getWord "+ currentSW.getWord());
			
													// Process each attribute
													catSeq += " "+(String)currentSW.getCat();
													subcatSeq += " "+(String)currentSW.getSubcat();
													lemmaSeq += " "+(String)currentSW.getLemma();
													mphSeq += " "+(String)currentSW.getMph();
			
												}
												catSeq = catSeq.trim();
												subcatSeq = subcatSeq.trim();
												lemmaSeq = lemmaSeq.trim();
												mphSeq = mphSeq.trim();
			
												//System.err.println("Debug: currentWordFormOcc >"+currentWordFormOcc+"<");
												// will overide any previous existing catint sequence assigned by MW analysis
			
												// Similary to the counting of word forms we count multi word forms
												
												CollectionUtilities.incrementKeyCounter(
														aWordForms.getWordFormCatCounter(wordsString).getCatMap(), 
														catSeq);
			
												// Count the subcat occurrences depending on the word forms + cat
												CollectionUtilities.incrementKeyCounter(
														aWordForms.getWordCatFormOtherCounters(wordsString+" "+catSeq).getSubcatMap(), 
														subcatSeq);
			
												// Count the lemma occurrences depending on the word forms + cat
												CollectionUtilities.incrementKeyCounter(
														aWordForms.getWordCatFormOtherCounters(wordsString+" "+catSeq).getLemmaMap(), 
														lemmaSeq);
			
												// Count the mph occurrences depending on the word forms + cat
												CollectionUtilities.incrementKeyCounter(
														aWordForms.getWordCatFormOtherCounters(wordsString+" "+catSeq).getMphMap(), 
														mphSeq);
			
												//		aMW.addMostProbableCatintSequence(currentWordFormOcc, catSeq);
												//		aMW.addMostProbableSubcatSequence(currentWordFormOcc, subcatSeq);
												//		aMW.addMostProbableLemmaSequence(currentWordFormOcc, lemmaSeq);
												//		aMW.addMostProbableMphSequence(currentWordFormOcc, mphSeq);
			
												//features = features.trim();
												//	if (aMW.getMostProbableMphSequence().keySet().isEmpty()) {
													numberOfMWWithAtLeastOneCorrespondingSWSeq++;
													numberOfMWOccurrencesCorrespondingToASWSeq += aMW.getOccurrence();
													//	}
												//aMW.addFeaturesFromSWSeq(features);
											//	if (aMW.getMostProbableMphSequence().keySet().size() > 1) {
											//		numberOfMWWithSeveralSWSeqFeaturesSet.add(wordsString);
											//	}
			
												if (aMW.getDesambiguisationCase() != -1) numberOfAlreadyDesambiguatedCaseCorrespondingToASWSeq++;
												if (aMW.getNumberOfNullCatintValue() >0) 
													aMW.setDesambiguisationCase(MultiWordDesambiguationCase.MWWithACorrespondingSWSequence);
												//System.out.println("Debug: MATCHED "+wordsString+ " cats "+aMW.getCatsFromSWSeqSet().toString());
											}
										}
									}
								}
							}
						}
					}
				}
			
				System.err.println("Info: # of multi words lemma with at least one corresponding simple word sequence = "+numberOfMWWithAtLeastOneCorrespondingSWSeq);
				System.err.println("Info: # of multi words occurrences with at least one corresponding simple word sequence  = "+numberOfMWOccurrencesCorrespondingToASWSeq);
				System.err.println("Info: # of multi words lemma with several simple word sequences  = "+numberOfMWWithSeveralSWSeqFeaturesSet.size());
				System.err.println("Info: # of corresponding to another ambiguous cat and corresponding to simple word sequences  = "+numberOfAlreadyDesambiguatedCaseCorrespondingToASWSeq);
			
			}

}